package com.skyeye;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.skyeye.entity.User;
import com.skyeye.mapper.UserMapperPlus;
import com.skyeye.util.DatabaseUtil;
import com.skyeye.util.MyBatisPlusUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.time.LocalDateTime;
import java.util.List;

import static org.junit.Assert.*;

/**
 * 使用MyBatis-Plus的QueryWrapper进行用户CRUD操作的单元测试类
 * 展示QueryWrapper的便捷查询功能
 */
public class UserMapperPlusTest {
    
    private SqlSession sqlSession;
    private UserMapperPlus userMapper;
    
    @Before
    public void setUp() {
        // 创建测试表
//        DatabaseUtil.createTestTable();
        
        // 获取SqlSession和Mapper
        sqlSession = MyBatisPlusUtil.getSqlSession();
        userMapper = sqlSession.getMapper(UserMapperPlus.class);
        
        System.out.println("🚀 开始执行MyBatis-Plus QueryWrapper测试...");
    }
    
//    @After
    public void tearDown() {
        // 清空测试数据
        DatabaseUtil.truncateTestTable();
        
        // 关闭SqlSession
        MyBatisPlusUtil.closeSqlSession(sqlSession);
        
        System.out.println("🧹 MyBatis-Plus测试完成，清理测试数据");
    }
    
    /**
     * 测试基本插入
     */
    @Test
    public void testInsert() {
        User user = new User("QueryWrapper用户1", "query1@example.com", 25, "13800138001");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        int result = userMapper.insert(user);
        assertEquals("应该插入1条记录", 1, result);
        assertNotNull("用户ID应该被设置", user.getId());
        
        System.out.println("✅ MyBatis-Plus插入成功！ID: " + user.getId());
    }
    
    /**
     * 测试使用QueryWrapper查询单个用户
     */
    @Test
    public void testSelectOne() {
        // 先插入测试数据
        User testUser = createTestUser("QueryWrapper用户2", "query2@example.com", 30, "13800138002");
        
        // 使用QueryWrapper查询
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", "QueryWrapper用户2");
        
        User foundUser = userMapper.selectOne(queryWrapper);
        
        assertNotNull("应该查询到用户", foundUser);
        assertEquals("用户名应该匹配", "QueryWrapper用户2", foundUser.getUsername());
        
        System.out.println("✅ QueryWrapper查询单个用户成功！");
        System.out.println("查询到的用户: " + foundUser);
    }
    
    /**
     * 测试使用QueryWrapper查询列表
     */
    @Test
    public void testSelectList() {
        // 插入测试数据
        createTestUser("QueryWrapper用户A", "queryA@example.com", 20, "13800138010");
        createTestUser("QueryWrapper用户B", "queryB@example.com", 25, "13800138011");
        createTestUser("QueryWrapper用户C", "queryC@example.com", 30, "13800138012");
        
        // 使用QueryWrapper查询年龄大于等于25的用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("age", 25)
                    .orderByAsc("age");
        
        List<User> users = userMapper.selectList(queryWrapper);
        
        assertEquals("应该查询到2个用户（年龄>=25）", 2, users.size());
        
        System.out.println("✅ QueryWrapper查询列表成功！");
        System.out.println("查询到的用户数量: " + users.size());
        for (User user : users) {
            System.out.println("用户信息: " + user);
        }
    }
    
    /**
     * 测试使用QueryWrapper多条件查询
     */
    @Test
    public void testSelectListWithMultipleConditions() {
        // 插入测试数据
        createTestUser("QueryWrapper用户X", "queryX@example.com", 25, "13800138020");
        createTestUser("QueryWrapper用户Y", "queryY@example.com", 30, "13800138021");
        createTestUser("QueryWrapper用户Z", "queryZ@example.com", 35, "13800138022");
        
        // 使用QueryWrapper多条件查询：年龄在25-30之间
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("age", 25)
                    .le("age", 30)
                    .like("username", "QueryWrapper")
                    .orderByDesc("age");
        
        List<User> users = userMapper.selectList(queryWrapper);
        
        assertEquals("应该查询到2个用户（年龄25-30）", 2, users.size());
        
        System.out.println("✅ QueryWrapper多条件查询成功！");
        System.out.println("查询到的用户数量: " + users.size());
    }
    
    /**
     * 测试使用QueryWrapper模糊查询
     */
    @Test
    public void testSelectListWithLike() {
        // 插入测试数据
        createTestUser("张三", "zhangsan@example.com", 25, "13800138030");
        createTestUser("张四", "zhangsi@example.com", 26, "13800138031");
        createTestUser("李五", "liwu@example.com", 27, "13800138032");
        
        // 使用QueryWrapper模糊查询
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("username", "张")
                    .orderByAsc("id");
        
        List<User> users = userMapper.selectList(queryWrapper);
        
        assertEquals("应该查询到2个用户（用户名包含'张'）", 2, users.size());
        
        System.out.println("✅ QueryWrapper模糊查询成功！");
        System.out.println("查询到的用户数量: " + users.size());
    }
    
    /**
     * 测试使用QueryWrapper统计数量
     */
    @Test
    public void testSelectCount() {
        // 插入测试数据
        createTestUser("统计用户1", "count1@example.com", 20, "13800138040");
        createTestUser("统计用户2", "count2@example.com", 25, "13800138041");
        createTestUser("统计用户3", "count3@example.com", 30, "13800138042");
        
        // 使用QueryWrapper统计年龄大于等于25的用户数量
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("age", 25);
        
        Long count = userMapper.selectCount(queryWrapper);
        
        assertEquals("应该统计到2个用户（年龄>=25）", Long.valueOf(2), count);
        
        System.out.println("✅ QueryWrapper统计数量成功！");
        System.out.println("符合条件的用户数量: " + count);
    }
    
    /**
     * 测试使用QueryWrapper更新
     */
    @Test
    public void testUpdateWithUpdateWrapper() {
        // 先插入测试数据
        User testUser = createTestUser("更新用户", "update@example.com", 25, "13800138050");
        
        // 使用UpdateWrapper更新
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", testUser.getId())
                    .set("email", "update_new@example.com")
                    .set("age", 26)
                    .set("update_time", LocalDateTime.now());
        
        int result = userMapper.update(null, updateWrapper);
        
        assertEquals("应该更新1条记录", 1, result);
        
        // 验证更新结果
        User updatedUser = userMapper.selectById(testUser.getId());
        assertEquals("邮箱应该已更新", "update_new@example.com", updatedUser.getEmail());
        assertEquals("年龄应该已更新", Integer.valueOf(26), updatedUser.getAge());
        
        System.out.println("✅ UpdateWrapper更新成功！");
        System.out.println("更新后的用户: " + updatedUser);
    }
    
    /**
     * 测试使用QueryWrapper删除
     */
    @Test
    public void testDeleteWithQueryWrapper() {
        // 先插入测试数据
        createTestUser("删除用户1", "delete1@example.com", 20, "13800138060");
        createTestUser("删除用户2", "delete2@example.com", 25, "13800138061");
        createTestUser("保留用户", "keep@example.com", 30, "13800138062");
        
        // 使用QueryWrapper删除年龄小于等于25的用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.le("age", 25);
        
        int result = userMapper.delete(queryWrapper);
        
        assertEquals("应该删除2条记录", 2, result);
        
        // 验证删除结果
        Long count = userMapper.selectCount(null);
        assertEquals("应该还剩1个用户", Long.valueOf(1), count);
        
        System.out.println("✅ QueryWrapper删除成功！");
        System.out.println("删除后剩余用户数量: " + count);
    }
    
    /**
     * 测试使用QueryWrapper的IN查询
     */
    @Test
    public void testSelectListWithIn() {
        // 插入测试数据
        User user1 = createTestUser("IN用户1", "in1@example.com", 20, "13800138070");
        User user2 = createTestUser("IN用户2", "in2@example.com", 25, "13800138071");
        User user3 = createTestUser("IN用户3", "in3@example.com", 30, "13800138072");
        
        // 使用QueryWrapper的IN查询
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", user1.getId(), user3.getId())
                    .orderByAsc("id");
        
        List<User> users = userMapper.selectList(queryWrapper);
        
        assertEquals("应该查询到2个用户", 2, users.size());
        
        System.out.println("✅ QueryWrapper IN查询成功！");
        System.out.println("查询到的用户数量: " + users.size());
    }
    
    /**
     * 测试使用QueryWrapper的复杂条件查询
     */
    @Test
    public void testSelectListWithComplexConditions() {
        // 插入测试数据
        createTestUser("复杂查询用户1", "complex1@example.com", 20, "13800138080");
        createTestUser("复杂查询用户2", "complex2@example.com", 25, "13800138081");
        createTestUser("复杂查询用户3", "complex3@example.com", 30, "13800138082");
        createTestUser("复杂查询用户4", "complex4@example.com", 35, "13800138083");
        
        // 使用QueryWrapper复杂条件查询
        // 年龄在20-30之间，或者年龄等于35
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper
                        .ge("age", 20)
                        .le("age", 30))
                    .or()
                    .eq("age", 35)
                    .orderByAsc("age");
        
        List<User> users = userMapper.selectList(queryWrapper);
        
        assertEquals("应该查询到4个用户", 4, users.size());
        
        System.out.println("✅ QueryWrapper复杂条件查询成功！");
        System.out.println("查询到的用户数量: " + users.size());
    }
    
    /**
     * 测试使用QueryWrapper的字段选择
     */
    @Test
    public void testSelectListWithSelectFields() {
        // 插入测试数据
        createTestUser("字段选择用户", "select@example.com", 25, "13800138090");
        
        // 使用QueryWrapper只查询指定字段
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "username", "email")
                    .eq("username", "字段选择用户");
        
        List<User> users = userMapper.selectList(queryWrapper);
        
        assertEquals("应该查询到1个用户", 1, users.size());
        assertNotNull("ID应该存在", users.get(0).getId());
        assertNotNull("用户名应该存在", users.get(0).getUsername());
        assertNotNull("邮箱应该存在", users.get(0).getEmail());
        
        System.out.println("✅ QueryWrapper字段选择成功！");
        System.out.println("查询到的用户: " + users.get(0));
    }
    
    /**
     * 辅助方法：创建测试用户并返回用户对象
     */
    private User createTestUser(String username, String email, int age, String phone) {
        User user = new User(username, email, age, phone);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        userMapper.insert(user);
        return user;
    }
}
